home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / String Extractor⁄Localization / Scanner / FolderUtils.c < prev    next >
Encoding:
Text File  |  1993-06-18  |  12.3 KB  |  604 lines  |  [TEXT/KAHL]

  1. /*    © 1993 Jon Wätte, Stockholm
  2.  *
  3.  *    This is unpublished proprietary source code, and may not be used,
  4.  *    released, copied, stored in a retrieval system, modified or shown
  5.  *    to anyone else without the copyright holders’ prior written
  6.  *    permission.
  7.  *
  8.  *    Denna källkod skyddas av upphovsrätt, och klassas som opublicerat
  9.  *    hemligt material. Ingen användning, kopiering, avskrivning,
  10.  *    vidarebefodring, ändring eller publicering av denna källkod eller
  11.  *    del härav får ske utan att skriftligt tillstånd först erhållits från
  12.  *    upphovsrättsinnehavaren.
  13.  */
  14.  
  15. //    FolderUtils.c
  16.  
  17.  
  18. #include "FolderUtils.h"
  19. #include "h+utils.h"
  20. #include "TBUtilities.h"
  21. #include <string.h>
  22.  
  23. #define CHECK(x) if(err=x){goto erret;}
  24. #define memcopy(s,d,l) memmove(d,s,l)
  25.  
  26.  
  27. static    CInfoPBRec        sInfo ;
  28. static    Str255            sStr ;
  29. static    FSSpec            sSpec ;
  30.  
  31. static Boolean gCancelled = 0 ;
  32.  
  33.  
  34. short
  35. GetFolderID ( FSSpec * fss , long * dirID )
  36. {
  37. short err ;
  38.  
  39.     if ( ! fss -> name [ 0 ] ) {
  40.         return fss -> parID ;
  41.     }
  42.     BlockClear ( sInfo ) ;
  43.     sInfo . hFileInfo . ioNamePtr = fss -> name ;
  44.     sInfo . hFileInfo . ioDirID = fss -> parID ;
  45.     sInfo . hFileInfo . ioVRefNum = fss -> vRefNum ;
  46.  
  47.     err = PBGetCatInfoSync ( & sInfo ) ;
  48.  
  49.     if ( ! err && ! ( sInfo . hFileInfo . ioFlAttrib & 0x10 ) ) {
  50.         err = dirNFErr ; /* Not a folder */
  51.     }
  52.     if ( ! err ) {
  53.         * dirID = sInfo . hFileInfo . ioDirID ;
  54.     }
  55.     return err ;
  56. }
  57.  
  58.  
  59. short
  60. GetFullPathHandle ( FSSpec * fss , Handle * h )
  61. {
  62.     Handle    tempH = NULL ;
  63.     short err ;
  64.     FSSpec fs = * fss ;
  65.  
  66.     while ( fs . parID > 1 ) {
  67.  
  68.         tempH = NULL ;
  69.  
  70. //        ASSERT ( fs . name [ 0 ] < 32 && fs . name [ 0 ] > 0 ) ;
  71.  
  72.         PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] ) ;
  73.         CHECK ( MemError ( ) ) ;
  74.         PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
  75.         CHECK ( MemError ( ) ) ;
  76.         HandAndHand ( * h , tempH ) ;
  77.         CHECK ( MemError ( ) ) ;
  78.         SetHandleSize ( * h , 0L ) ;
  79.         HandAndHand ( tempH , * h ) ;
  80.         CHECK ( MemError ( ) ) ;
  81.         DisposeHandle ( tempH ) ;
  82.         tempH = NULL ;
  83.         CHECK ( GetFolderParent ( & fs , & sSpec ) ) ;
  84.         fs = sSpec ;
  85.     }
  86.     CHECK ( GetVolName ( fs . vRefNum , fs . name ) ) ;
  87.  
  88. //    ASSERT ( fs . name [ 0 ] < 32 && fs . name [ 0 ] > 0 ) ;
  89.  
  90.     PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] ) ;
  91.     CHECK ( MemError ( ) ) ;
  92.     PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
  93.     CHECK ( MemError ( ) ) ;
  94.     HandAndHand ( * h , tempH ) ;
  95.     CHECK ( MemError ( ) ) ;
  96.     SetHandleSize ( * h , 0L ) ;
  97.     HandAndHand ( tempH , * h ) ;
  98.     CHECK ( MemError ( ) ) ;
  99.     DisposeHandle ( tempH ) ;
  100.     tempH = NULL ;
  101.  
  102.     if ( ! IsFolder ( fss ) ) {
  103.  
  104.         SetHandleSize ( * h , GetHandleSize ( * h ) - 1 ) ; // Remove colon
  105.     }
  106.  
  107.     return 0 ;
  108.  
  109. erret :
  110.     if ( tempH ) {
  111.  
  112.         DisposeHandle ( tempH ) ;
  113.     }
  114.     SetHandleSize ( * h , 0L ) ;
  115.  
  116.     return err ;
  117. }
  118.  
  119.  
  120. short
  121. GetFullPathString ( FSSpec * fss , unsigned char * str )
  122. {
  123.     short err ;
  124.     FSSpec fs = * fss ;
  125.  
  126.     * str = 0 ;
  127.  
  128.     while ( fs . parID > 1 ) {
  129.  
  130.         CopyPString ( fs . name , sStr ) ;
  131.         ConcatPStrings ( sStr , "\P:" ) ;
  132.         ConcatPStrings ( sStr , str ) ;
  133.         CopyPString ( sStr , str ) ;
  134.         CHECK ( GetFolderParent ( & fs , & sSpec ) ) ;
  135.         fs = sSpec ;
  136.     }
  137.     CHECK ( GetVolName ( fs . vRefNum , fs . name ) ) ;
  138.  
  139.     CopyPString ( fs . name , sStr ) ;
  140.     ConcatPStrings ( sStr , "\P:" ) ;
  141.     ConcatPStrings ( sStr , str ) ;
  142.     CopyPString ( sStr , str ) ;
  143.  
  144.     if ( * str == 255 ) {
  145.  
  146.         str [ 1 ] = '…' ;
  147.     }
  148.  
  149.     if ( ! IsFolder ( fss ) ) {
  150.  
  151.         str [ 0 ] -- ;
  152.     }
  153.  
  154.     return 0 ;
  155.  
  156. erret :
  157.  
  158.     return err ;
  159. }
  160.  
  161.  
  162. Boolean
  163. IsFolder ( FSSpec * fss )
  164. {
  165.     short err ;
  166.  
  167.     BlockClear ( sInfo ) ;
  168.     CopyPString ( fss -> name , sStr ) ;
  169.  
  170.     sInfo . dirInfo . ioNamePtr = sStr ;
  171.     sInfo . dirInfo . ioVRefNum = fss -> vRefNum ;
  172.     sInfo . dirInfo . ioDrDirID = fss -> parID ;
  173.  
  174.     CHECK ( PBGetCatInfoSync ( & sInfo ) ) ;
  175.  
  176.     return 0x10 == ( sInfo . hFileInfo . ioFlAttrib & 0x10 ) ;
  177.  
  178. erret :
  179.  
  180.     return 0 ;
  181. }
  182.  
  183.  
  184. short
  185. GetFolderParent ( FSSpec * fss , FSSpec * par )
  186. {
  187.     short err ;
  188.     BlockClear ( sInfo ) ;
  189.  
  190.     sInfo . dirInfo . ioNamePtr = sStr ;
  191.     sInfo . dirInfo . ioVRefNum = fss -> vRefNum ;
  192.     sInfo . dirInfo . ioDrDirID = fss -> parID ;
  193.     sInfo . dirInfo . ioFDirIndex = -1 ;
  194.  
  195.     CHECK ( PBGetCatInfoSync ( & sInfo ) ) ;
  196.  
  197.     CHECK ( FSMakeFSSpec ( sInfo . dirInfo . ioVRefNum , sInfo . dirInfo . ioDrParID ,
  198.         sStr , par ) ) ;
  199.  
  200.     return 0 ;
  201.  
  202. erret :
  203.  
  204.     return err ;
  205. }
  206.  
  207.  
  208. #define kGetDirList 7
  209. #define kGetDirBTN 10
  210. #define kGetDirPrompt 11
  211. #define kNewDirBTN 12
  212. #define kGetFolderDLOG 210
  213.  
  214. static Boolean gDirSelectionFlag = 0 ;
  215. static Str255 gPrevSelectedName ;
  216. static Str32 gSelDirStrOne , gSelDirStrTwo ;
  217. static unsigned char * gPromptString = NULL ;
  218.  
  219. static short gVRefNum ;
  220. static long gDirID ;
  221.  
  222.  
  223. // Filter out files
  224. //
  225. static pascal Boolean
  226. MyCustomGetDirectoryFileFilter ( CInfoPBPtr myPB , Ptr myDataPtr )
  227. {
  228.     return ! ( myPB -> hFileInfo . ioFlAttrib & 0x10 ) ;
  229. }
  230.  
  231. // Set the button title ( Select “foldername” )
  232. //
  233. static void
  234. SetButtonTitle ( Handle buttonHandle , unsigned char * name , Rect * buttonRect )
  235. {
  236.     short        resultCode ;
  237.     short        width ;
  238.     Str255        conc ;
  239.  
  240.     memcopy ( name , gPrevSelectedName , name [ 0 ] + 1 ) ;
  241.  
  242.     width = buttonRect -> right - buttonRect -> left - ( StringWidth ( gSelDirStrOne ) +
  243.         StringWidth ( gSelDirStrTwo ) ) ;
  244.     resultCode = TruncString ( width , name , smTruncMiddle ) ;
  245.  
  246.     if ( resultCode < 0 ) { // Error : 1 - truncated, 0 - unchanged, <0 - error
  247.  
  248.         SetCTitle ( ( ControlHandle ) buttonHandle , name ) ;
  249.  
  250.     } else {
  251.  
  252.         memcopy ( gSelDirStrOne , conc , gSelDirStrOne [ 0 ] + 1 ) ;
  253.         memcopy ( name + 1 , conc + conc [ 0 ] + 1 , name [ 0 ] ) ;
  254.         conc [ 0 ] += name [ 0 ] ;
  255.         memcopy ( gSelDirStrTwo + 1 , conc + conc [ 0 ] + 1 , gSelDirStrTwo [ 0 ] ) ;
  256.         conc [ 0 ] += gSelDirStrTwo [ 0 ] ;
  257.         SetCTitle ( ( ControlHandle ) buttonHandle , conc ) ;
  258.     }
  259.  
  260.     ValidRect ( buttonRect ) ;
  261. }
  262.  
  263.  
  264. static void
  265. MakeNewFolder ( void )
  266. {
  267.     DialogPtr dp = NULL ;
  268.     Handle h ;
  269.     Rect r ;
  270.     short k , itemHit ;
  271.     Str255 s ;
  272.     long id ;
  273.     GrafPtr oldP ;
  274.  
  275.     GetPort ( & oldP ) ;
  276.  
  277.     dp = GetNewDialog ( 211 , NULL , NULL ) ;
  278.     if ( ! dp ) {
  279.  
  280.         SysBeep ( 20 ) ;
  281.         return ;
  282.     }
  283.  
  284.     GetDItem ( dp , 4 , & k , & h , & r ) ;
  285.     SetDItem ( dp , 4 , k , ( Handle ) FrameItem , & r ) ;
  286.     SelIText ( dp , 3 , 0 , 32767 ) ;
  287.     SelectWindow ( dp ) ;
  288.     ShowWindow ( dp ) ;
  289.     SetPort ( dp ) ;
  290.     do {
  291.  
  292.         ModalDialog ( NULL , & itemHit ) ;
  293.         GetDItem ( dp , 3 , & k , & h , & r ) ;
  294.         GetIText ( h , s ) ;
  295.         if ( s [ 0 ] ) {
  296.  
  297.             int i , flag = 0 ;
  298.  
  299.             if ( s [ 1 ] == '.' ) {
  300.  
  301.                 s [ 1 ] = '•' ;
  302.                 flag = 1 ;
  303.             }
  304.             for ( i = 1 ; i <= s [ 0 ] ; i ++ ) {
  305.  
  306.                 if ( s [ i ] == ':' ) {
  307.  
  308.                     s [ i ] = '•' ;
  309.                     flag = 1 ;
  310.                 }
  311.             }
  312.             if ( flag ) {
  313.  
  314.                 SetIText ( h , s ) ;
  315.             }
  316.         }
  317.     } while ( itemHit != 1 && itemHit != 2 ) ;
  318.  
  319.     if ( itemHit == 1 && s [ 0 ] ) {
  320.  
  321.         if ( DirCreate ( - SFSaveDisk , CurDirStore , s , & id ) ) {
  322.  
  323.             SysBeep ( 20 ) ;
  324.         }
  325.     }
  326.     DisposeDialog ( dp ) ;
  327.  
  328.     SetPort ( oldP ) ;
  329. }
  330.  
  331.  
  332. // Hook into the modal dialog to check what items come & go
  333. //
  334. static pascal short
  335. MyCustomGetDirectoryDlogHook ( short item , DialogPtr theDialog ,
  336.     StandardFileReply * mySFRPtr )
  337. {
  338.     Handle                h ;
  339.     short                kind ;
  340.     Rect                r ;
  341.     Str255                selectedName ;
  342.     CInfoPBRec            pb ;
  343.     OSErr                err ;
  344.     short                retVal = item ;
  345.  
  346. //    CustomGet calls dialog hook for both
  347. //    main and subsidiary dialog boxes. Check 
  348. //    here that the refCon indicates dialog 
  349. //    record describes main dialog box
  350.  
  351.     if ( GetWRefCon ( theDialog ) == sfMainDialogRefCon ) {
  352.  
  353. //        if ( item == //•
  354.         GetDItem ( theDialog , kGetDirBTN , & kind , & h , & r ) ;
  355.  
  356.         if ( item == sfHookFirstCall ) {
  357.  
  358. //    Set the static text item
  359.  
  360.             GetDItem ( theDialog , kGetDirPrompt , & kind , & h , & r ) ;
  361.             SetIText ( ( Handle ) h , gPromptString ) ;
  362.  
  363. //    Dont forget to set the handle back
  364.  
  365.             GetDItem ( theDialog , kGetDirBTN , & kind , & h , & r ) ;
  366.  
  367. //    determine current folder name and
  368. //    set title of button to select it
  369.  
  370.             pb . hFileInfo . ioCompletion = NULL ;
  371.             pb . hFileInfo . ioNamePtr = selectedName ;
  372.             pb . hFileInfo . ioVRefNum = - SFSaveDisk ;
  373.             pb . hFileInfo . ioFDirIndex = -1 ;
  374.             pb . hFileInfo . ioDirID = CurDirStore ;
  375.  
  376.             err = PBGetCatInfo ( & pb , 0 ) ;
  377.             gVRefNum = pb . hFileInfo . ioVRefNum ;
  378.             gDirID = pb . dirInfo . ioDrParID ;
  379.  
  380.             if ( err ) {
  381.                 gDirSelectionFlag = 0 ;
  382.             } else {
  383.                 gDirSelectionFlag = 1 ;
  384.             }
  385.             SetButtonTitle ( h , selectedName , & r ) ;
  386.  
  387.         } else {
  388.  
  389. //    track name of folder that can be selected
  390.  
  391.             if ( ( mySFRPtr -> sfIsFolder ) || ( mySFRPtr -> sfIsVolume ) ) {
  392.  
  393.                 memcopy ( mySFRPtr -> sfFile . name , selectedName ,
  394.                     mySFRPtr -> sfFile . name [ 0 ] + 1 ) ;
  395.                 gVRefNum = mySFRPtr -> sfFile . vRefNum ;
  396.                 gDirID = mySFRPtr -> sfFile . parID ;
  397.  
  398.             } else {
  399.  
  400.                 pb . hFileInfo . ioCompletion = NULL ;
  401.                 pb . hFileInfo . ioNamePtr = selectedName ;
  402.                 pb . hFileInfo . ioVRefNum = mySFRPtr -> sfFile . vRefNum ;
  403.                 pb . hFileInfo . ioFDirIndex = -1 ;
  404.                 pb . hFileInfo . ioDirID = mySFRPtr -> sfFile . parID ;
  405.  
  406.                 err = PBGetCatInfo ( & pb , 0 ) ;
  407.                 if ( err ) {
  408.                     gDirSelectionFlag = 0 ;
  409.                 } else {
  410.                     gDirSelectionFlag = 1 ;
  411.                 }
  412.                 gVRefNum = pb . hFileInfo . ioVRefNum ;
  413.                 gDirID = pb . dirInfo . ioDrParID ;
  414.             }
  415.  
  416. //    change folder name in button title as needed
  417.  
  418.             if ( ! EqualString ( gPrevSelectedName , selectedName , 0 , 1 ) ) {                                                
  419.                 SetButtonTitle ( h , selectedName , & r ) ;
  420.             }
  421.  
  422.             switch ( item ) {
  423.  
  424.             case kGetDirBTN :    // Force return by faking a cancel
  425.                 gDirSelectionFlag = 1 ;
  426.                 retVal = sfItemCancelButton ;
  427.                 break ;
  428.  
  429.             case sfItemCancelButton :    // Real cancel ; fill in global
  430.                 gDirSelectionFlag = 0 ;
  431.                 gCancelled = 1 ;
  432.                 break ;
  433.  
  434.             case kNewDirBTN :    // Make New Folder
  435.                 MakeNewFolder ( ) ;
  436.                 retVal = sfHookRebuildList ;
  437.                 break ;
  438.             }
  439.         }
  440.     }
  441.  
  442.     return retVal ;
  443. }
  444.  
  445.  
  446. static Boolean
  447. GetAFolder ( short * vol , long * dir , long * par , unsigned char * name ,
  448.     unsigned char * prompt )
  449. {
  450.     Point where = { -1 , -1 } ;
  451.     Boolean hasMoof = 0 ;
  452.     StandardFileReply sfr ;
  453.  
  454.     gCancelled = 0 ;
  455.     GetIndString ( gSelDirStrOne , 1025 , 1 ) ;
  456.     GetIndString ( gSelDirStrTwo , 1025 , 2 ) ;
  457.     gPromptString = prompt ;
  458.  
  459.     CustomGetFile ( ( void * ) MyCustomGetDirectoryFileFilter , -1 , NULL , & sfr ,
  460.         kGetFolderDLOG , where , ( void * ) MyCustomGetDirectoryDlogHook , NULL , NULL ,
  461.         NULL , & sfr ) ;
  462.  
  463.     if ( gDirSelectionFlag && ! gCancelled ) {
  464.  
  465.         memcopy ( gPrevSelectedName , name , gPrevSelectedName [ 0 ] + 1 ) ;
  466.         hasMoof = 1 ;
  467. //        * vol = sfr . sfFile . vRefNum ;
  468. //        * dir = sfr . sfFile . parID ;
  469.         * vol = gVRefNum ;
  470.         * par = gDirID ;
  471.  
  472.         if ( sfr . sfIsVolume ) {
  473.  
  474.             name [ ++ name [ 0 ] ] = ':' ;
  475.             * par = 0 ;
  476.         }
  477.         {
  478.             CInfoPBRec info ;
  479.             info . hFileInfo . ioCompletion = 0 ;
  480.             info . hFileInfo . ioFDirIndex = 0 ;
  481.             info . hFileInfo . ioDirID = * par ;
  482.             info . hFileInfo . ioVRefNum = * vol ;
  483.             info . hFileInfo . ioNamePtr = gPrevSelectedName ;
  484.             if ( ! PBGetCatInfo ( & info , 0 ) ) {
  485.                 * dir = info . dirInfo . ioDrDirID ;
  486.             }
  487.         }
  488.     }
  489.     gDirSelectionFlag = 0 ;
  490.  
  491.     return hasMoof && ! gCancelled ;
  492. }
  493.  
  494.  
  495. Boolean
  496. GetAFolderFSS ( FSSpec * fss , unsigned char * prompt )
  497. {
  498.     long dirID ;
  499.  
  500.     return GetAFolder ( & ( fss -> vRefNum ) , & dirID , & ( fss -> parID ) ,
  501.         fss -> name , prompt ) ;
  502. }
  503.  
  504.  
  505. short
  506. GetVolName ( short vol , unsigned char * name )
  507. {
  508.     short err ;
  509.     HVolumeParam hv ;
  510.  
  511.     BlockClear ( hv ) ;
  512.  
  513.     hv . ioNamePtr = name ;
  514.     hv . ioVRefNum = vol ;
  515.  
  516.     CHECK ( PBHGetVInfoSync ( ( void * ) & hv ) ) ;
  517.  
  518.     return 0 ;
  519.  
  520. erret :
  521.  
  522.     return err ;
  523. }
  524.  
  525.  
  526. short
  527. GetFolderName ( short vol , long dir , unsigned char * name )
  528. {
  529.     BlockClear ( sInfo ) ;
  530.  
  531.     sInfo . hFileInfo . ioNamePtr = name ;
  532.     sInfo . hFileInfo . ioVRefNum = vol ;
  533.     sInfo . hFileInfo . ioDirID = dir ;
  534.     sInfo . hFileInfo . ioFDirIndex = -1 ;
  535.  
  536.     return PBGetCatInfoSync ( & sInfo ) ;
  537. }
  538.  
  539.  
  540. short
  541. TouchFolder ( short vRefNum , long dirID )
  542. {
  543.     short err ;
  544.  
  545.     BlockClear ( sInfo ) ;
  546.  
  547.     sInfo . hFileInfo . ioNamePtr = sStr ;
  548.     sInfo . hFileInfo . ioDirID = dirID ;
  549.     sInfo . hFileInfo . ioVRefNum = vRefNum ;
  550.     sInfo . hFileInfo . ioFDirIndex = -1 ;
  551.  
  552.     err = PBGetCatInfoSync ( & sInfo ) ;
  553.  
  554.     if ( ! err ) {
  555.  
  556.         sInfo . hFileInfo . ioCompletion = 0 ;
  557.         sInfo . hFileInfo . ioFVersNum = 0 ;
  558.         GetDateTime ( & sInfo . hFileInfo . ioFlMdDat ) ;
  559.         err = PBSetCatInfoSync ( & sInfo ) ;
  560.     }
  561.  
  562.     return err ;
  563. }
  564.  
  565.  
  566. short
  567. GetVolNum ( unsigned char * findName , unsigned long date , short * vol )
  568. {
  569.     int ix ;
  570.     short err ;
  571.     HVolumeParam hv ;
  572.     unsigned char name [ 64 ] ;
  573.  
  574.     BlockClear ( hv ) ;
  575.  
  576.     for ( ix = 1 ; ix > 0 ; ix ++ ) {
  577.  
  578.         hv . ioNamePtr = name ;
  579.         hv . ioVRefNum = 0x8000 ;
  580.         hv . ioVolIndex = ix ;
  581.  
  582.         CHECK ( PBHGetVInfoSync ( ( void * ) & hv ) ) ;
  583.  
  584.         if ( ! IUEqualString ( name , findName ) ) {
  585.  
  586.             if ( date == hv . ioVCrDate || ! date ) {
  587.  
  588.                 * vol = hv . ioVRefNum ;
  589.                 goto isOK ;
  590.             }
  591.         }
  592.     }
  593.     err = nsvErr ;
  594.     goto erret ;
  595.  
  596. isOK :
  597.  
  598.     return 0 ;
  599.  
  600. erret :
  601.  
  602.     return err ;
  603. }
  604.